////////////////////////////////////////////////////////////////////////////////
/*! \file
 * \brief Linux implementation file for the library-object.
 *
 * \author Ivo Wingelaar
 * \date 2011
 * \version 0.1.1
 * \copyright GNU Lesser General Public License v3
 */
////////////////////////////////////////////////////////////////////////////////

#include "MythDynamic_LibraryLinux_C.hpp"

#ifdef _MYTH_LINUX_

namespace Myth
{
namespace Dynamic
{

////////////////////////////////////////////////////////////////////////////////
//! Default constructor.
LibraryLinux_C::LibraryLinux_C(void) :
    mLibrary(0),
    mError("")
{
    mLibrary = dlopen(0, 0);
}

////////////////////////////////////////////////////////////////////////////////
//! Constructor.
LibraryLinux_C::LibraryLinux_C(const std::string& name) :
    mLibrary(0),
    mError("")
{
    dlerror(); // flush error message.
    mLibrary = dlopen(name.c_str(), RTLD_LAZY | RTLD_LOCAL);
    char* t = dlerror();
    if(t)
        mError = t;
}

////////////////////////////////////////////////////////////////////////////////
//! Virtual destructor.
LibraryLinux_C::~LibraryLinux_C(void)
{
    if(mLibrary != NULL)
        dlclose(mLibrary);
}

////////////////////////////////////////////////////////////////////////////////
//! Searches for the specified symbol and returns it if found.
void* LibraryLinux_C::get_symbol(const std::string& symbol_name, std::string* error_message)
{
    if(mLibrary != NULL)
    {
        dlerror(); // flush error message.
        void* sym = dlsym(mLibrary, symbol_name.c_str());

        if(error_message && !sym)
        {
            char* t = dlerror();
            if(t)
                *error_message = t;
        }

        return sym;
    }
    else
        return NULL;
}

////////////////////////////////////////////////////////////////////////////////
//! Returns if the library was loaded succesfuly.
bool LibraryLinux_C::is_valid(void) const
{
    return (mLibrary != NULL);
}

////////////////////////////////////////////////////////////////////////////////
//! Returns the system-specific error message.
std::string LibraryLinux_C::get_error(void) const
{
    return mError;
}

} // namespace Dynamic
} // namespace Myth

#endif // _MYTH_LINUX_
